package genetica.cruce;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Random;
import java.util.SortedSet;
import java.util.TreeSet;

import genetica.cromosomas.Cromosoma;
import genetica.cromosomas.genes.Gen;

public class CruceVarianteOX extends AlgoritmoCruce {

	public CruceVarianteOX(double pCruce) {
		super(pCruce);

	}

	@Override
	public void cruce(Cromosoma prog1, Cromosoma prog2) {
		// inicializo los hijos
		Random generador = new Random();
		int tam = prog1.getGenes().size();
		int nCruzados = generador.nextInt(tam);
		int[] posiciones = new int[nCruzados];
		int[] posicion2 = new int[nCruzados];
		int[] posicion1 = new int[nCruzados];
		
		Gen[] desc1 = new Gen[prog1.getGenes().size()];
		Gen[] desc2 = new Gen[prog1.getGenes().size()];

		for (int i = 0; i < tam; i++){
			desc1[i] = prog2.getGenes().get(i);
			desc2[i] = prog1.getGenes().get(i);
		}
		TreeSet<Integer> arbol = new TreeSet<Integer>();
		while (arbol.size() < nCruzados){
			arbol.add(generador.nextInt(tam));
		}
		int pos = 0;
		while (arbol.size() != 0){
			posiciones[pos++] = arbol.pollFirst();
		}
		Gen[] genes1 = new Gen[nCruzados];

		Gen[] genes2 = new Gen[nCruzados];
		
		for (int i = 0;i<nCruzados;i++){
			genes1[i] = prog1.getGenes().get(i);
			posicion2[i] = getIndex(prog2.getGenes(), genes1[i]);
			
			genes2[i] = prog2.getGenes().get(i);
			posicion1[i] = getIndex(prog1.getGenes(),genes2[i]);
		}
		for (int i = 0; i< genes1.length;i++){
			desc1[posicion2[i]] = genes1[i];
			desc2[posicion1[i]] = genes2[i];
		}
		prog1.setGenes(new ArrayList<Gen>(Arrays.asList(desc1)));
		prog2.setGenes(new ArrayList<Gen>(Arrays.asList(desc2)));
	}
	
	private static int getIndex(ArrayList<Gen> genes, Gen actual) {
		for (int i = 0; i < genes.size(); i++)
			if (genes.get(i).equals(actual))
				return i;
		return -1;
	}
	@Override
	public String toString() {
		return "Variante del algoritmo de cruce OX";
	}
}
